{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "Exercise 6 - Question.ipynb",
      "version": "0.3.2",
      "provenance": [],
      "collapsed_sections": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "code",
      "metadata": {
        "id": "dn-6c02VmqiN",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# In this exercise you will train a CNN on the FULL Cats-v-dogs dataset\n",
        "# This will require you doing a lot of data preprocessing because\n",
        "# the dataset isn't split into training and validation for you\n",
        "# This code block has all the required inputs\n",
        "import os\n",
        "import zipfile\n",
        "import random\n",
        "import tensorflow as tf\n",
        "from tensorflow.keras.optimizers import RMSprop\n",
        "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
        "from shutil import copyfile"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "3sd9dQWa23aj",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 204
        },
        "outputId": "46428230-dbb0-44e4-f8b3-c38e2db57faa"
      },
      "source": [
        "# This code block downloads the full Cats-v-Dogs dataset and stores it as \n",
        "# cats-and-dogs.zip. It then unzips it to /tmp\n",
        "# which will create a tmp/PetImages directory containing subdirectories\n",
        "# called 'Cat' and 'Dog' (that's how the original researchers structured it)\n",
        "# If the URL doesn't work, \n",
        "# .   visit https://www.microsoft.com/en-us/download/confirmation.aspx?id=54765\n",
        "# And right click on the 'Download Manually' link to get a new URL\n",
        "\n",
        "!wget --no-check-certificate \\\n",
        "    \"https://download.microsoft.com/download/3/E/1/3E1C3F21-ECDB-4869-8368-6DEBA77B919F/kagglecatsanddogs_3367a.zip\" \\\n",
        "    -O \"/tmp/cats-and-dogs.zip\"\n",
        "\n",
        "local_zip = '/tmp/cats-and-dogs.zip'\n",
        "zip_ref = zipfile.ZipFile(local_zip, 'r')\n",
        "zip_ref.extractall('/tmp')\n",
        "zip_ref.close()\n"
      ],
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "--2019-06-15 07:11:57--  https://download.microsoft.com/download/3/E/1/3E1C3F21-ECDB-4869-8368-6DEBA77B919F/kagglecatsanddogs_3367a.zip\n",
            "Resolving download.microsoft.com (download.microsoft.com)... 184.26.80.188, 2600:1409:3000:48e::e59, 2600:1409:3000:4a4::e59\n",
            "Connecting to download.microsoft.com (download.microsoft.com)|184.26.80.188|:443... connected.\n",
            "HTTP request sent, awaiting response... 200 OK\n",
            "Length: 824894548 (787M) [application/octet-stream]\n",
            "Saving to: ‘/tmp/cats-and-dogs.zip’\n",
            "\n",
            "/tmp/cats-and-dogs. 100%[===================>] 786.68M   101MB/s    in 7.3s    \n",
            "\n",
            "2019-06-15 07:12:04 (108 MB/s) - ‘/tmp/cats-and-dogs.zip’ saved [824894548/824894548]\n",
            "\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "gi3yD62a6X3S",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 51
        },
        "outputId": "9ddb1a72-b3a2-4525-9a5f-cb660af1a452"
      },
      "source": [
        "print(len(os.listdir('/tmp/PetImages/Cat/')))\n",
        "print(len(os.listdir('/tmp/PetImages/Dog/')))\n",
        "\n",
        "# Expected Output:\n",
        "# 12501\n",
        "# 12501"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "12501\n",
            "12501\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "F-QkLjxpmyK2",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# Use os.mkdir to create your directories\n",
        "# You will need a directory for cats-v-dogs, and subdirectories for training\n",
        "# and testing. These in turn will need subdirectories for 'cats' and 'dogs'\n",
        "try:\n",
        "    os.mkdir('/tmp/cats-v-dogs')\n",
        "    os.mkdir('/tmp/cats-v-dogs/training')\n",
        "    os.mkdir('/tmp/cats-v-dogs/testing')\n",
        "    os.mkdir('/tmp/cats-v-dogs/training/cats')\n",
        "    os.mkdir('/tmp/cats-v-dogs/training/dogs')\n",
        "    os.mkdir('/tmp/cats-v-dogs/testing/cats')\n",
        "    os.mkdir('/tmp/cats-v-dogs/testing/dogs')\n",
        "except OSError:\n",
        "    pass"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zvSODo0f9LaU",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 51
        },
        "outputId": "07e59797-d25f-4956-d6ca-9ad3e37ade11"
      },
      "source": [
        "# Write a python function called split_data which takes\n",
        "# a SOURCE directory containing the files\n",
        "# a TRAINING directory that a portion of the files will be copied to\n",
        "# a TESTING directory that a portion of the files will be copie to\n",
        "# a SPLIT SIZE to determine the portion\n",
        "# The files should also be randomized, so that the training set is a random\n",
        "# X% of the files, and the test set is the remaining files\n",
        "# SO, for example, if SOURCE is PetImages/Cat, and SPLIT SIZE is .9\n",
        "# Then 90% of the images in PetImages/Cat will be copied to the TRAINING dir\n",
        "# and 10% of the images will be copied to the TESTING dir\n",
        "# Also -- All images should be checked, and if they have a zero file length,\n",
        "# they will not be copied over\n",
        "#\n",
        "# os.listdir(DIRECTORY) gives you a listing of the contents of that directory\n",
        "# os.path.getsize(PATH) gives you the size of the file\n",
        "# copyfile(source, destination) copies a file from source to destination\n",
        "# random.sample(list, len(list)) shuffles a list\n",
        "def split_data(SOURCE, TRAINING, TESTING, SPLIT_SIZE):\n",
        "    files = []\n",
        "    for filename in os.listdir(SOURCE):\n",
        "        file = SOURCE + filename\n",
        "        if os.path.getsize(file) > 0:\n",
        "            files.append(filename)\n",
        "        else:\n",
        "            print(filename + \" is zero length, so ignoring.\")\n",
        "\n",
        "    training_length = int(len(files) * SPLIT_SIZE)\n",
        "    testing_length = int(len(files) - training_length)\n",
        "    shuffled_set = random.sample(files, len(files))\n",
        "    training_set = shuffled_set[0:training_length]\n",
        "    testing_set = shuffled_set[:testing_length]\n",
        "\n",
        "    for filename in training_set:\n",
        "        this_file = SOURCE + filename\n",
        "        destination = TRAINING + filename\n",
        "        copyfile(this_file, destination)\n",
        "\n",
        "    for filename in testing_set:\n",
        "        this_file = SOURCE + filename\n",
        "        destination = TESTING + filename\n",
        "        copyfile(this_file, destination)\n",
        "\n",
        "CAT_SOURCE_DIR = \"/tmp/PetImages/Cat/\"\n",
        "TRAINING_CATS_DIR = \"/tmp/cats-v-dogs/training/cats/\"\n",
        "TESTING_CATS_DIR = \"/tmp/cats-v-dogs/testing/cats/\"\n",
        "DOG_SOURCE_DIR = \"/tmp/PetImages/Dog/\"\n",
        "TRAINING_DOGS_DIR = \"/tmp/cats-v-dogs/training/dogs/\"\n",
        "TESTING_DOGS_DIR = \"/tmp/cats-v-dogs/testing/dogs/\"\n",
        "\n",
        "split_size = .9\n",
        "split_data(CAT_SOURCE_DIR, TRAINING_CATS_DIR, TESTING_CATS_DIR, split_size)\n",
        "split_data(DOG_SOURCE_DIR, TRAINING_DOGS_DIR, TESTING_DOGS_DIR, split_size)\n",
        "\n",
        "# Expected output\n",
        "# 666.jpg is zero length, so ignoring\n",
        "# 11702.jpg is zero length, so ignoring"
      ],
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "666.jpg is zero length, so ignoring.\n",
            "11702.jpg is zero length, so ignoring.\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "luthalB76ufC",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 85
        },
        "outputId": "05fce37c-fb44-4724-c461-69faf8ca400b"
      },
      "source": [
        "print(len(os.listdir('/tmp/cats-v-dogs/training/cats/')))\n",
        "print(len(os.listdir('/tmp/cats-v-dogs/training/dogs/')))\n",
        "print(len(os.listdir('/tmp/cats-v-dogs/testing/cats/')))\n",
        "print(len(os.listdir('/tmp/cats-v-dogs/testing/dogs/')))\n",
        "\n",
        "# Expected output:\n",
        "# 11250\n",
        "# 11250\n",
        "# 1250\n",
        "# 1250"
      ],
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "11250\n",
            "11250\n",
            "1250\n",
            "1250\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "-BQrav4anTmj",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 156
        },
        "outputId": "32dbd157-bc8e-419f-b3a1-83872ba265ec"
      },
      "source": [
        "# DEFINE A KERAS MODEL TO CLASSIFY CATS V DOGS\n",
        "# USE AT LEAST 3 CONVOLUTION LAYERS\n",
        "model = tf.keras.models.Sequential([\n",
        "    tf.keras.layers.Conv2D(16, (3, 3), activation='relu', input_shape=(150, 150, 3)),\n",
        "    tf.keras.layers.MaxPooling2D(2, 2),\n",
        "    tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),\n",
        "    tf.keras.layers.MaxPooling2D(2, 2),\n",
        "    tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),\n",
        "    tf.keras.layers.MaxPooling2D(2, 2),\n",
        "    tf.keras.layers.Flatten(),\n",
        "    tf.keras.layers.Dense(512, activation='relu'),\n",
        "    tf.keras.layers.Dense(1, activation='sigmoid')\n",
        "])\n",
        "\n",
        "model.compile(optimizer=RMSprop(lr=0.001), loss='binary_crossentropy', metrics=['acc'])"
      ],
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "WARNING: Logging before flag parsing goes to stderr.\n",
            "W0615 07:14:35.334333 140089941018496 deprecation.py:506] From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/init_ops.py:1251: calling VarianceScaling.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n",
            "Instructions for updating:\n",
            "Call initializer instance with the dtype argument instead of passing it to the constructor\n",
            "W0615 07:14:35.649746 140089941018496 deprecation.py:323] From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/nn_impl.py:180: add_dispatch_support.<locals>.wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n",
            "Instructions for updating:\n",
            "Use tf.where in 2.0, which has the same broadcast rule as np.where\n"
          ],
          "name": "stderr"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "mlNjoJ5D61N6",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 51
        },
        "outputId": "4a6b8ff3-1ea8-40e8-84ad-fed254039241"
      },
      "source": [
        "TRAINING_DIR = \"/tmp/cats-v-dogs/training/\"\n",
        "train_datagen = ImageDataGenerator(rescale=1./255,\n",
        "      rotation_range=40,\n",
        "      width_shift_range=0.2,\n",
        "      height_shift_range=0.2,\n",
        "      shear_range=0.2,\n",
        "      zoom_range=0.2,\n",
        "      horizontal_flip=True,\n",
        "      fill_mode='nearest')\n",
        "train_generator = train_datagen.flow_from_directory(TRAINING_DIR,\n",
        "                                                    batch_size=100,\n",
        "                                                    class_mode='binary',\n",
        "                                                    target_size=(150, 150))\n",
        "\n",
        "VALIDATION_DIR = \"/tmp/cats-v-dogs/testing/\"\n",
        "validation_datagen = ImageDataGenerator(rescale=1./255,\n",
        "      rotation_range=40,\n",
        "      width_shift_range=0.2,\n",
        "      height_shift_range=0.2,\n",
        "      shear_range=0.2,\n",
        "      zoom_range=0.2,\n",
        "      horizontal_flip=True,\n",
        "      fill_mode='nearest')\n",
        "validation_generator = validation_datagen.flow_from_directory(VALIDATION_DIR,\n",
        "                                                              batch_size=100,\n",
        "                                                              class_mode='binary',\n",
        "                                                              target_size=(150, 150))\n",
        "\n",
        "\n",
        "# Expected Output:\n",
        "# Found 22498 images belonging to 2 classes.\n",
        "# Found 2500 images belonging to 2 classes."
      ],
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Found 22498 images belonging to 2 classes.\n",
            "Found 2498 images belonging to 2 classes.\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "KyS4n53w7DxC",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 2621
        },
        "outputId": "df9a1834-80cf-4fc3-a522-570833a9dfd9"
      },
      "source": [
        "history = model.fit_generator(train_generator,\n",
        "                              epochs=15,\n",
        "                              verbose=1,\n",
        "                              validation_data=validation_generator)\n",
        "\n",
        "# The expectation here is that the model will train, and that accuracy will be > 95% on both training and validation\n",
        "# i.e. acc:A1 and val_acc:A2 will be visible, and both A1 and A2 will be > .9"
      ],
      "execution_count": 10,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Epoch 1/15\n",
            " 25/225 [==>...........................] - ETA: 2:16 - loss: 1.5010 - acc: 0.5092"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 18350080 bytes but only got 0. Skipping tag 0\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:742: UserWarning: Corrupt EXIF data.  Expecting to read 12 bytes but only got 6. \n",
            "  warnings.warn(str(msg))\n"
          ],
          "name": "stderr"
        },
        {
          "output_type": "stream",
          "text": [
            " 54/225 [======>.......................] - ETA: 1:57 - loss: 1.0742 - acc: 0.5280"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 80000 bytes but only got 0. Skipping tag 64640\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 65536 bytes but only got 0. Skipping tag 3\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 307363840 bytes but only got 0. Skipping tag 5\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 307888128 bytes but only got 0. Skipping tag 5\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 131072 bytes but only got 0. Skipping tag 3\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 328728576 bytes but only got 0. Skipping tag 4\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 1385474 bytes but only got 5357. Skipping tag 513\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 3846701056 bytes but only got 0. Skipping tag 2\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 3300917248 bytes but only got 0. Skipping tag 7\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 196867 bytes but only got 5357. Skipping tag 0\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:742: UserWarning: Corrupt EXIF data.  Expecting to read 12 bytes but only got 8. \n",
            "  warnings.warn(str(msg))\n"
          ],
          "name": "stderr"
        },
        {
          "output_type": "stream",
          "text": [
            " 92/225 [===========>..................] - ETA: 1:32 - loss: 0.9147 - acc: 0.5471"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 404094976 bytes but only got 0. Skipping tag 5\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 404619264 bytes but only got 0. Skipping tag 5\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 425459712 bytes but only got 0. Skipping tag 4\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 1385474 bytes but only got 6833. Skipping tag 513\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 196867 bytes but only got 6833. Skipping tag 0\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n"
          ],
          "name": "stderr"
        },
        {
          "output_type": "stream",
          "text": [
            " 97/225 [===========>..................] - ETA: 1:28 - loss: 0.9028 - acc: 0.5501"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 32 bytes but only got 0. Skipping tag 270\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 5 bytes but only got 0. Skipping tag 271\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 8 bytes but only got 0. Skipping tag 272\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 8 bytes but only got 0. Skipping tag 282\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 8 bytes but only got 0. Skipping tag 283\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 20 bytes but only got 0. Skipping tag 306\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 48 bytes but only got 0. Skipping tag 532\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:742: UserWarning: Corrupt EXIF data.  Expecting to read 2 bytes but only got 0. \n",
            "  warnings.warn(str(msg))\n"
          ],
          "name": "stderr"
        },
        {
          "output_type": "stream",
          "text": [
            "197/225 [=========================>....] - ETA: 19s - loss: 0.7927 - acc: 0.5678"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 209715200 bytes but only got 0. Skipping tag 48\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 52428800 bytes but only got 0. Skipping tag 0\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 6468665344 bytes but only got 0. Skipping tag 0\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 1050744 bytes but only got 7027. Skipping tag 48\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 422313984 bytes but only got 0. Skipping tag 5\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 422838272 bytes but only got 0. Skipping tag 5\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 3368026112 bytes but only got 0. Skipping tag 7\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 134479872 bytes but only got 0. Skipping tag 7\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 428867584 bytes but only got 0. Skipping tag 10\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 429391872 bytes but only got 0. Skipping tag 5\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 2031616 bytes but only got 0. Skipping tag 3\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 429916160 bytes but only got 0. Skipping tag 5\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 21299200 bytes but only got 0. Skipping tag 4\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 24313856 bytes but only got 0. Skipping tag 4\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 453771264 bytes but only got 7032. Skipping tag 4\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 131073 bytes but only got 7028. Skipping tag 0\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 393216 bytes but only got 0. Skipping tag 3\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 416415744 bytes but only got 0. Skipping tag 5\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 416940032 bytes but only got 0. Skipping tag 5\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 524288 bytes but only got 0. Skipping tag 4\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 415825920 bytes but only got 7032. Skipping tag 4\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:742: UserWarning: Corrupt EXIF data.  Expecting to read 12 bytes but only got 2. \n",
            "  warnings.warn(str(msg))\n"
          ],
          "name": "stderr"
        },
        {
          "output_type": "stream",
          "text": [
            "203/225 [==========================>...] - ETA: 15s - loss: 0.7882 - acc: 0.5701"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 6553600 bytes but only got 0. Skipping tag 49\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 1050744 bytes but only got 4951. Skipping tag 51\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 293339136 bytes but only got 0. Skipping tag 5\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 293863424 bytes but only got 0. Skipping tag 5\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 295698432 bytes but only got 0. Skipping tag 10\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 296222720 bytes but only got 0. Skipping tag 5\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 14745600 bytes but only got 0. Skipping tag 4\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 25624576 bytes but only got 0. Skipping tag 4\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 317718528 bytes but only got 4956. Skipping tag 4\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 131073 bytes but only got 4952. Skipping tag 0\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 287178752 bytes but only got 0. Skipping tag 5\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 287703040 bytes but only got 0. Skipping tag 5\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n",
            "/usr/local/lib/python3.6/dist-packages/PIL/TiffImagePlugin.py:725: UserWarning: Possibly corrupt EXIF data.  Expecting to read 286654464 bytes but only got 4956. Skipping tag 4\n",
            "  \" Skipping tag %s\" % (size, len(data), tag))\n"
          ],
          "name": "stderr"
        },
        {
          "output_type": "stream",
          "text": [
            "225/225 [==============================] - 176s 783ms/step - loss: 0.7734 - acc: 0.5779 - val_loss: 0.6376 - val_acc: 0.6429\n",
            "Epoch 2/15\n",
            "225/225 [==============================] - 166s 737ms/step - loss: 0.6289 - acc: 0.6553 - val_loss: 0.5736 - val_acc: 0.6946\n",
            "Epoch 3/15\n",
            "225/225 [==============================] - 165s 731ms/step - loss: 0.5917 - acc: 0.6889 - val_loss: 0.5459 - val_acc: 0.7114\n",
            "Epoch 4/15\n",
            "225/225 [==============================] - 165s 731ms/step - loss: 0.5607 - acc: 0.7123 - val_loss: 0.5636 - val_acc: 0.6898\n",
            "Epoch 5/15\n",
            "225/225 [==============================] - 165s 731ms/step - loss: 0.5412 - acc: 0.7252 - val_loss: 0.5248 - val_acc: 0.7378\n",
            "Epoch 6/15\n",
            "225/225 [==============================] - 165s 734ms/step - loss: 0.5266 - acc: 0.7389 - val_loss: 0.5298 - val_acc: 0.7334\n",
            "Epoch 7/15\n",
            "225/225 [==============================] - 165s 733ms/step - loss: 0.5107 - acc: 0.7506 - val_loss: 0.4687 - val_acc: 0.7746\n",
            "Epoch 8/15\n",
            "225/225 [==============================] - 167s 743ms/step - loss: 0.5029 - acc: 0.7560 - val_loss: 0.4719 - val_acc: 0.7786\n",
            "Epoch 9/15\n",
            "225/225 [==============================] - 168s 746ms/step - loss: 0.4888 - acc: 0.7649 - val_loss: 0.4562 - val_acc: 0.7818\n",
            "Epoch 10/15\n",
            "225/225 [==============================] - 168s 744ms/step - loss: 0.4827 - acc: 0.7693 - val_loss: 0.4702 - val_acc: 0.7794\n",
            "Epoch 11/15\n",
            "225/225 [==============================] - 167s 741ms/step - loss: 0.4701 - acc: 0.7768 - val_loss: 0.4384 - val_acc: 0.7978\n",
            "Epoch 12/15\n",
            "225/225 [==============================] - 167s 741ms/step - loss: 0.4696 - acc: 0.7774 - val_loss: 0.4264 - val_acc: 0.7950\n",
            "Epoch 13/15\n",
            "225/225 [==============================] - 167s 741ms/step - loss: 0.4588 - acc: 0.7851 - val_loss: 0.4107 - val_acc: 0.8106\n",
            "Epoch 14/15\n",
            "225/225 [==============================] - 167s 741ms/step - loss: 0.4494 - acc: 0.7903 - val_loss: 0.4335 - val_acc: 0.7914\n",
            "Epoch 15/15\n",
            "225/225 [==============================] - 165s 735ms/step - loss: 0.4472 - acc: 0.7926 - val_loss: 0.4167 - val_acc: 0.8139\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "MWZrJN4-65RC",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 562
        },
        "outputId": "3f1d125e-9334-4709-e926-e025ae246e37"
      },
      "source": [
        "# PLOT LOSS AND ACCURACY\n",
        "%matplotlib inline\n",
        "\n",
        "import matplotlib.image  as mpimg\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "#-----------------------------------------------------------\n",
        "# Retrieve a list of list results on training and test data\n",
        "# sets for each training epoch\n",
        "#-----------------------------------------------------------\n",
        "acc=history.history['acc']\n",
        "val_acc=history.history['val_acc']\n",
        "loss=history.history['loss']\n",
        "val_loss=history.history['val_loss']\n",
        "\n",
        "epochs=range(len(acc)) # Get number of epochs\n",
        "\n",
        "#------------------------------------------------\n",
        "# Plot training and validation accuracy per epoch\n",
        "#------------------------------------------------\n",
        "plt.plot(epochs, acc, 'r', \"Training Accuracy\")\n",
        "plt.plot(epochs, val_acc, 'b', \"Validation Accuracy\")\n",
        "plt.title('Training and validation accuracy')\n",
        "plt.figure()\n",
        "\n",
        "#------------------------------------------------\n",
        "# Plot training and validation loss per epoch\n",
        "#------------------------------------------------\n",
        "plt.plot(epochs, loss, 'r', \"Training Loss\")\n",
        "plt.plot(epochs, val_loss, 'b', \"Validation Loss\")\n",
        "\n",
        "\n",
        "plt.title('Training and validation loss')\n",
        "\n",
        "# Desired output. Charts with training and validation metrics. No crash :)"
      ],
      "execution_count": 11,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "Text(0.5, 1.0, 'Training and validation loss')"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 11
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nToQ5c9JjRm66yUFpZt2Kw9JKW7YMpkxJT0E+8ECYNQtOPbXcVZmZbXMOS2vetGkwYUK6p+tll6Xj\nk62+352Z2fbFYWmbW7cOPv95+MAH0oWYjzySznht10WYZmbbB5/gY41mzUr3dZ0zB847L7UoKyvL\nXZWZWdm5ZWnpocuXXw7veAcsWZJuW3fllQ5KM7OMW5bd3YIF6QSe+++Hk05KNxpo02NGzMy2fw7L\n7mz58nRJyNq1KSTPPtv3dTUza4bDsjsbPBi+/W14//th3LhyV2Nm1mk5LLu7z3623BWYmXV6PsHH\nzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMws\nh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PS\nzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMws\nh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PS\nzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMws\nh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PS\nzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMws\nh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PS\nzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMws\nh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PS\nzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMws\nh8PSzMwsh8PSzMwsh8PSzMwsh8PSzMwsxxaHpaSdJD2ZDYslLSx6v0Mr13GtpL1ylvmcpI9vab1F\n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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAbMAAAEICAYAAADV4BoxAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJzt3XmcVNWd/vHPwyKyCbKqgDZbFIwI\ngls0CS5RNGomy7jgZEzMvs04mlUziTFO4owmmSyOozEzZlRcYuKPbBqNSjQxUREXVGQRUBEQZAfZ\n+/v749yyi6Z6X6pu87xfr/vqW1W37v1WN/TT59xz71FEYGZmlmedyl2AmZlZSznMzMws9xxmZmaW\new4zMzPLPYeZmZnlnsPMzMxyz2FmBkjqLGmjpANbc9tykjRKUqtfeyPpZEmLix7PlfTOxmzbjGPd\nKOnS5r6/nv1eKemm1t6vlU+Xchdg1hySNhY97AFsBXZmjz8VEbc2ZX8RsRPo1drb7gki4uDW2I+k\njwP/EBGTi/b98dbYt3V8DjPLpYh4K0yyv/w/HhF/rGt7SV0iYkd71GZm7c/djNYhZd1Id0i6TdIG\n4B8kHSvpb5LWSlom6UeSumbbd5EUkqqyx7dkr98jaYOkv0oa3tRts9dPkzRP0jpJP5b0F0kfqaPu\nxtT4KUkLJK2R9KOi93aW9ANJqyQtBKbU8/25TNLttZ67VtL3s/WPS5qTfZ6XslZTXftaImlytt5D\n0s1Zbc8DE2tt+3VJC7P9Pi/prOz5w4CfAO/MunDfKPreXl70/k9nn32VpP8naf/GfG8aIun9WT1r\nJT0o6eCi1y6VtFTSekkvFn3WYyTNyp5/XdLVjT2etYGI8OIl1wuwGDi51nNXAtuAM0l/tHUHjgSO\nJvVIjADmAZ/Ptu8CBFCVPb4FeAOYBHQF7gBuaca2g4ANwPuy1y4GtgMfqeOzNKbG6UAfoApYXfjs\nwOeB54GhQH/g4fRfvORxRgAbgZ5F+14BTMoen5ltI+BEYDMwLnvtZGBx0b6WAJOz9WuAGcC+wEHA\nC7W2PRvYP/uZTM1qGJy99nFgRq06bwEuz9ZPyWocD+wN/BfwYGO+NyU+/5XATdn6mKyOE7Of0aXA\n3Gz9UOBlYL9s2+HAiGz9CeC8bL03cHS5/y/syYtbZtaR/TkifhMR1RGxOSKeiIjHImJHRCwEbgDe\nXc/774qImRGxHbiV9Eu0qdueATwdEdOz135ACr6SGlnjdyNiXUQsJgVH4VhnAz+IiCURsQq4qp7j\nLASeI4UswHuANRExM3v9NxGxMJIHgQeAkoM8ajkbuDIi1kTEy6TWVvFx74yIZdnPZBrpD5FJjdgv\nwPnAjRHxdERsAb4KvFvS0KJt6vre1Odc4NcR8WD2M7qKFIhHAztIwXlo1lW9KPveQfqjZLSk/hGx\nISIea+TnsDbgMLOO7NXiB5IOkfQ7ScslrQeuAAbU8/7lRetvUv+gj7q2PaC4jogIUkumpEbW2Khj\nkVoU9ZkGnJetT80eF+o4Q9JjklZLWktqFdX3vSrYv74aJH1E0jNZd95a4JBG7hfS53trfxGxHlgD\nDCnapik/s7r2W036GQ2JiLnAJaSfw4qs23q/bNOPAmOBuZIel3R6Iz+HtQGHmXVktYelX09qjYyK\niH2Ab5C60drSMlK3HwCSxK6/fGtrSY3LgGFFjxu6dOBO4GRJQ0gttGlZjd2Bu4DvkroA+wL3NbKO\n5XXVIGkEcB3wGaB/tt8Xi/bb0GUES0ldl4X99SZ1Z77WiLqast9OpJ/ZawARcUtEHEfqYuxM+r4Q\nEXMj4lxSV/L3gF9K2ruFtVgzOcxsT9IbWAdskjQG+FQ7HPO3wBGSzpTUBfhnYGAb1XgncJGkIZL6\nA1+pb+OIWA78GbgJmBsR87OXugF7ASuBnZLOAE5qQg2XSuqrdB3e54te60UKrJWkXP8EqWVW8Dow\ntDDgpYTbgI9JGiepGylUHomIOlu6Taj5LEmTs2N/iXSe8zFJYySdkB1vc7ZUkz7AhyUNyFpy67LP\nVt3CWqyZHGa2J7kEuID0i+p60kCNNhURrwPnAN8HVgEjgadI18W1do3Xkc5tzSYNTrirEe+ZRhrQ\n8VYXY0SsBf4FuJs0iOJDpFBujG+SWoiLgXuA/yva77PAj4HHs20OBorPM90PzAdel1TcXVh4/72k\n7r67s/cfSDqP1iIR8Tzpe34dKWinAGdl58+6Af9BOs+5nNQSvCx76+nAHKXRstcA50TEtpbWY82j\n1IVvZu1BUmdSt9aHIuKRctdj1lG4ZWbWxiRNybrdugH/ShoF93iZyzLrUBxmZm3veGAhqQvrVOD9\nEVFXN6OZNYO7Gc3MLPfcMjMzs9zzjYbbyYABA6KqqqrcZZiZ5cqTTz75RkTUdzkL4DBrN1VVVcyc\nObPcZZiZ5Yqkhu5kA7ib0czMOgCHmZmZ5Z7DzMzMcs9hZmZmuecwMzOz3Ks3zCQ9JOnUWs9dJOm6\nBt63Mft6gKSSNzuVNENSvZPyZcfqUfT495L61veexpB0uaQvtnQ/ZmZWGRpqmd1GmoW12LnZ8w2K\niKUR8aHmFJa5CHgrzCLi9OyO3mZmZm9pKMzuAt4raS8ASVWkWVkfkdRL0gOSZkmaLel9td8sqUrS\nc9l6d0m3S5oj6W6ge9F210maKel5Sd/Knvun7FgPSXooe26xpAHZ+sWSnsuWi4qON0fST7N93ZdN\nNNgodeyzZzbz7zPZ8+dkz18l6QVJz0q6prHHMDOz1lfvRdMRsVrS48BpwHRSq+zOiAhJW0g3TF2f\nBczfJP066r7Z42eANyNijKRxwKyi1y7LjtUZeEDSuIj4kaSLgRMi4o3iHUmaSJqy/GjSLLWPSfoT\naQr10cB5EfEJSXcCHwRuaegbUc8+RwBLI+K92XZ9sokP3w8ckn0vSnZ9Svok8EmAAw9saNJfMzNr\nrsYMACnuaizuYhTwHUnPAn8kTQU/uJ79vIssVLJJ+p4teu1sSbNIkxYeCoxtoKbjgbsjYlNEbAR+\nBbwze21RRDydrT8JVDWwr4b2ORt4j6R/l/TOiFhHmlV2C/AzSR8A3iy1w4i4ISImRcSkgQMbvBuL\nmZk1U2PCbDpwkqQjgB4R8WT2/Pmk6d8nRsR40pTneze1AEnDgS8CJ0XEOOB3zdlPkeKpNXbSwlt2\nRcQ84AhSqF0p6RsRsQM4itQNewZwb0uOYWZmLdNgmGWtlIeA/2HXgR99gBURsV3SCcBBDezqYWAq\ngKS3A+Oy5/cBNgHrJA0mdWkWbAB6l9jXI8DfSeohqSepy6+ls/aW3KekA0jdo7cAVwNHSOoF9ImI\n35Omlz+8hcc2M7MWaGyr5TbgbnYd2Xgr8BtJs4GZwIsN7OM64H8lzQHmkLoAiYhnJD2Vvf9V4C9F\n77kBuFfS0og4ofBkRMySdBM1s/XeGBFPZQNUGuvrhUEe2T6H1rHPU4GrJVWTZgj+DClgp0vam9Td\nenETjmtmZq3Mk3O2k0mTJoXvmm9m1jSSnoyIeq9JBt8BxMzMOgCHmZmZ5Z7DzMzMcs9hZmZmuecw\nMzOz3HOYmZlZ7jnMzMws9xxmZmaWew4zMzPLPYeZmZnlnsPMzMxyz2FmZma55zAzM7Pcc5iZmVnu\nOczMzCz3HGZmZpZ7DjMzM8s9h5mZmeWew8zMzHLPYWZmZrnnMDMzs9xzmJmZWe45zMzMLPccZmZm\nlnsOMzMzyz2HmZmZ5Z7DzMzMcs9hZmZmuecwMzOz3HOYmZlZ7jnMzMws9xxmZmaWew4zMzPLPYeZ\nmZnlnsPMzMxyz2FmZma55zAzM7Pcc5jlQUS5KzAzq2gOs0q2fTt86lNw9dXlrsTMrKI5zCpZly6w\nejVceik88ki5qzEzq1gOs0omwY03wvDhcO65sGJFuSsyM6tIDrNK16cP3HVXaqFNnQo7d5a7IjOz\niuMwy4PDD4ef/AQeeACuuKLc1ZiZVRyHWV5ceCFccAF8+9tw333lrsbMrKI4zPJCgmuvhbFj4fzz\nYcmScldkZlYxHGZ50rNnOn+2ZQucc04aum9mZg6z3DnkEPjpT+HRR+FrXyt3NWZmFcFhlkfnnguf\n/Sx873swfXq5qzEzKzuHWV59//swcWIaFLJwYbmrMTMrK4dZXnXrBr/4RRoY8vd/n86jmZntoRxm\neTZ8OPz85zBrFlx8cbmrMTMrG4dZ3p11FnzpS3DddTBtWrmrMTMrC4dZR/Bv/wbHHw+f/CTMmVPu\naszM2p3DrCPo2hVuvx169IAPfQg2bSp3RWZm7cph1lEMGZK6GefMgc98xhN6mtkexWHWkZx8Mnzz\nm3DzzfCzn5W7GjOzduMw62i+/vUUap//PDz9dLmrMTNrFw6zjqZzZ7j1VujfP11/tm5duSsyM2tz\nDrOOaNAguOMOWLQIPvYxnz8zsw7PYdZRHX88XHUV/PKX8KMflbsaM7M25TDryC65JF1U/cUvwt/+\nVu5qzMzajMOsI5Pgpptg6FA4+2xYtarcFZmZtQmHWUe3775pQs/XX4cPfxiqq8tdkZlZq3OY7Qkm\nToT//E+45550Hs3MrINxmFW4bdtaaUef/nSa1PNf/xVmzGilnZqZVQaHWQWLgDPPhKlTYcmSFu5M\nghtugNGjU6gtX94qNZqZVQKHWQXbuROOPhp+9Ss4+GC48soWzsHZu3c6f7Z+PZx3HuzY0Wq1mpmV\nk8OsgnXpAldcAS++CKedlnoIx4xJ4dbs66Df/vY099mMGXDQQXDRRfDoox4YYma55jDLgaqq1KB6\n4AHo1Qs++MF0+8XnnmvmDi+4ICXiUUfBf/83HHdcOsgll8Djj/uOIWaWOw6zHDnxRHjqKfjJT9LX\n8ePhC1+A1aubsbP3vx/uvhtWrEh32R8/Hn7849SvOXw4fPnL8OSTDjYzywWFf1m1i0mTJsXMmTNb\nbX+rVqVux+uvT5eSffvbaaLpzp1bsNO1a2H6dLjzTrjvvnRObeTIdMH12WfD4YengSRmZu1E0pMR\nMamh7dwyy6n+/eG//iu10A47DD77WTjiCPjTn1qw0759Uxfk736XLrL+2c9SmP3Hf8CECXDIISlB\nZ892i83MKorDLOfGjYMHH4Rf/CI1rCZPTo2ol19u4Y779YMLL4Q//CEN47/hBhg2DL7znXTQQw+F\nyy+HF15ohU9hZtYy7mZsJ63dzVjK5s1w9dXpJh8R8JWvpFNfPXq04kFWrEiDR+64IzUDI9IIybPP\nhnPOgbe9rRUPZmZ7usZ2MzrM2kl7hFnBK6+kELvjjtSYuuaaNE9nq5/uWr48TTFzxx3w5z+nYBs3\nDt77XpgyBY49Frp2beWDmtmexOfM9mAHHgi3354aTv36pQbT5Mnw9NOtfKD99oPPfQ4efhhefRV+\n+MM0GuXqq+Hd74YBA9J1BD/9aUpYM7M24pZZO2nPllmxnTvhxhvhsstgzRr4xCfSnUQGDGjDg65f\nny6Ku/fetBSCbOzY1GKbMgXe+U7Ye+82LMLMOgJ3M1aYcoVZwZo1abzGtdemu1p961vw0Y+m9TYV\nkW5hcu+96a79f/pTuntyjx5wwgk14TZqVBsXYmZ55DCrMOUOs4Lnn093sPrjH9M1aUcembogJ09O\nNwLp1auNC9i0KQVaodU2f356fuTImmA74QTo2bONCzGzPHCYVZhKCTNIjaWHH07XRc+Yke5gtWNH\nuhfkkUemLJk8Gd7xjnbIlJdeqgm2Bx+EN9+EvfaCd70Lpkxhx8lTWLj3WDp3ESNHtnEtZlZxHGYV\nppLCrLaNG9O9hmfMgIcegieeSOfaunZNt2+cPDkF3LHHtvIw/yKbN8O857YxZ/o85jywlDkvVPPC\n+qHMZzTb6AbAhCGvM/X0dZz76b4MnTDQdyMx2wM4zCpMJYdZbRs2wF/+ksJtxgyYObMm3I4+uqbl\nduyx0L170/a9di3MmbP7smhRzU1FOnVKt4ccU7WZsV3mMeaNR1gzbyW3bXgvT3AUopp3d32UqSMe\n44MnrKbfkSPTbVAOPbTt0tbMysJhVmHyFGa1rV9fE24PPZTuP1xdnXoDjzmmpuV2zDFpgGJEugSt\nVGgtW1az3732SvO0jRmz6/K2t9Ux0PGNN5h/zwKmTYNpf61i3rr96Mo2Tuf3TGUaZ/Jbuo8emq51\nO+ywtIwbByNGpIQ0s9xxmFWYPIdZbevXwyOP1ITbU0+lcOvWLd2+cfFiWLeuZvvevXcPrDFjUuur\nS5fm1RABs2bBtFuD227dybIVXei111Y+sN+jTN1xMyctvZkuZJOP9uiR7lJSCLdC0LXp9Qlm1hoc\nZhWmI4VZbWvXphuAPPRQGi05fHi6pKwQWgcc0Lant3buTAMkp01L876tWweDBgbnnLCCqSMf4+hN\nD6LZz6YbJL/xRs0b998/pe+IEbsv/fv7nJxZBXCYVZiOHGaVZMuWdDnbtGnwm9/A1q0pm6ZOhann\nBWP6vQ7PZsH27LOwYAEsXJj6RYv17l065EaMSDN0d+tWng9otodxmFUYh1n7W7cuzT86bVq6IUl1\ndZqDdOpUOO88GDq0aONNm1L/6MKFuy07XnqZTVs7s4mebKQXG+nNxoHD2TR4BBsHVLFx32Fs2md/\nNvYYxMZu/dnWpQfnTRUTJpTrk5t1HA6zCuMwK69ly9Kco9OmpevqpHQp29velnJs48a0FK8XHm/Z\n0vjjdGInnahmJ5358EEP829n/I2hEwfD6NFpGTTI3ZdmTeAwqzAOs8oxfz7cdlu62f+qVemuJ4Wl\nZ89mPO6yhV6rX6HX6y/R7dUFrJ/zGt+5bxI/XHQmimou4Xt8hX+nNxtT92Uh2GovPk9nthuHWYVx\nmO15Fi+Gy75WzbTbOzGo71a+dcqjfHzgdLq8NDcl6uLFafRKQd++6R6VpYKuX79yfQyzsnKYVRiH\n2Z7riSfgkkvS5QxjxqQZck4/HbR9Wwq0+fN3X15+ueYqckhhNnJkupygX7+09O9fs177cZ8+6eab\nZjnnMKswDrM9WwRMn54mTZ0/H048MU2aWucgka1b0wCU4oBbtAhWr65Z1q6t+4BSmluurrArfjx4\ncLqeYt992+Szm7WEw6zCOMwMYPt2uP76NB3P6tXwj/+Y5pfbZWRlY+3YkQKtEG6rVu0adsWPi9fr\nCsE+faCqKgVb7aWqyjMZWFk4zCqMw8yKrV0L3/1umpy7Uye4+GL4ylfaYX45SOfp1qypCbelS1N3\n56JFuy6bN+/6voED6w66gw5K9ycza2UOswrjMLNSFi9Os4BPm5ZG7V9xBXzsY82/zVeriYCVK3cP\nuEWLUtEvv5yamQUSDBmya8gNGgT77FP30q2bR29agxxmFcZhZvWpc5BIpf6u37kztehqh1xhfcmS\nXQewlNK1a+rarC/wai99+qT7ow0b5m7PPYTDrMI4zKwhtQeJnHRSGiQyfny5K2uGbdtSX+r69Q0v\n69bV/Vp9V6z365dCbdgwOPDA3deHDEmBabnmMKswDjNrrFYdJFLCjh0pI7ZuTUv37hU8kHHbtjTB\nXiHc1qyB116DV19Nyyuv1KyvXr3reyXYb79dg6528A0e7OmBKpzDrMI4zKypag8SufDC1Mu2dWtN\nGDXna3X17sfad9+a67ML120Xvpbjeu1t21I+FXouC1+XL4eJE1MX7HHH1Wp4bdpUOuSK1998c9cD\nde2a/krYb7/0Te7UKYVgqaWu1+p7T8+eaXaG4uWAA9JXd5M2isOswjjMrLkWL4ZLL0233+rUKY2b\n6NYtTWBa6mtTX9uwAV56KXVtLliQfvcX/1ooBF3tkBs1Kl2q1hw7dqTTaosX7x5Yixenxldx6Hbu\nnBpSAwbAM8+k1us++8B73pOC7bTTUj7UKyK13kqF3IoV6YARaSler2tpzDYbNqQbg27btns9vXvv\nGm61w66w3rt3BZ88bXsOswrjMLOWqq5unx6xLVtSqBTCrfhrqaArFXKjRqX9lAqqRYtSfhTfyUtK\nDaTCZW7FX6uq0muFEZ4bNqRZEH7/+7S89lp6fsKEFGynnw5HH11BN0CJSN2jS5emYCsspR7XvhwC\n0uSytYNu8OA0WrSwDByYvvbs2eGCz2FWYRxm1hEUbkxSO+QWLNj9Dly17b//7kFV+DpsWPMuU4tI\nU9MVgu3RR1NI9usHp56agu3UU9Pv+ooXkc4L1hd2hfUNG0rvo3v30iFXexk4MC05mJfPYVZhHGbW\n0W3dWtOie+ml9Hu1EFgHHpi6NdvamjVw//0p2O65J/UeSnDUUTXdkRMndoAxH5s3p+sAV6zYfSn1\nfKluTkgnYQsBN2BA+iF17Zr+sujatWYpflzXen2vHXVUs5vKDrMK4zAza1/V1TBrVk2r7fHHU+Nn\n0CCYMiWF2ymnVPBIztZSaPHVF3YrVsAbb6S/SLZvT+G3ffvu683Ni82bm/3XjMOswjjMzMpr5Uq4\n774UbPfem8aCdO4Mxx6brukbPjydmyssHmxYws6ddQddfSF4yinNbg47zCqMw8yscuzcmVpqhVbb\nrFm7b9O3767hVmrZZ598j7eISINyHn8c5sxJ40sOOQQOPrhyJkV3mFUYh5lZ5dq8OY2KXLKk7uX1\n13d/X69e9YfdQQelUKwUy5enW6cVL6tWld62T58UaoVwK6yPGtW+40YcZhXGYWaWb9u2pQGF9QXe\nsmW7X5Tev3/d1+m15fm6detg5sxdg+vVV9NrnTrBoYfCkUem5aij0uPly2Hu3LS8+GLN+pIlNfvt\n1CkN7CkVdIMHt35rzmFWYRxmZh3fjh2pBbdkSc0dTIovYSiESUH//qVDbvTopgXdli3w9NOpu7AQ\nXHPn1rw+cuSuwTVhQtPOCW7cCPPm7R508+btelOVffbZNdwK62PHNv+6P4dZhXGYmdnmzXVfp/fq\nq7sOFuzXr3TIjRiRWojFwTV7dgpSSNfzFYLryCNh0qTm36mlIdXVqXu2uBVXWC8O7vXrmz9Xn8Os\nwjjMzKw+W7akoCt155XaQVfQt28Kq+JW15Ah7V97KZs2pdoXLoQPfKD5+2lsmJV7CkAzMyNdhjV2\nbFpqKwTdggXpgvRBg1J4jRpVuReA9+yZpi9qrymMHGZmZhWuvqCzpEIz3czMrPEcZmZmlnsOMzMz\nyz2HmZmZ5Z7DzMzMcs9hZmZmuecwMzOz3HOYmZlZ7jnMzMws9xxmZmaWew4zMzPLPYeZmZnlnsPM\nzMxyz2FmZma55zAzM7Pcc5iZmVnuOczMzCz3HGZmZpZ7DjMzM8s9h5mZmeWew8zMzHLPYWZmZrnn\nMDMzs9xzmJmZWe45zMzMLPccZmZmlnsOMzMzyz2HmZmZ5Z7DzMzMcs9hZmZmuecwMzOz3HOYmZlZ\n7jnMzMws9xxmZmaWew4zMzPLPYeZmZnlnsPMzMxyz2FmZma55zAzM7Pcc5iZmVnuOczMzCz3HGZm\nZpZ7DjMzM8s9h5mZmeWew8zMzHLPYWZmZrnnMDMzs9xzmJmZWe45zMzMLPccZmZmlnsOMzMzyz2H\nmZmZ5Z7DzMzMcs9hZmZmuecwMzOz3HOYmZlZ7jnMzMws9xxmZmaWew4zMzPLPYeZmZnlnsPMzMxy\nz2FmZma55zAzM7Pcc5iZmVnuOczMzCz3HGZmZpZ7DjMzM8s9h5mZmeWew8zMzHLPYWZmZrnnMDMz\ns9xzmJmZWe45zMzMLPccZmZmlnsOMzMzyz2HmZmZ5V6Lw0xSf0lPZ8tySa8VPd6rkfv4X0kHN7DN\n5ySd39J6s339WdL41tiXmZmVX5eW7iAiVgHjASRdDmyMiGuKt5EkQBFRXcc+PtqI41zb0lrNzKxj\narNuRkmjJL0g6VbgeWB/STdIminpeUnfKNr2z5LGS+oiaa2kqyQ9I+mvkgZl21wp6aKi7a+S9Lik\nuZLekT3fU9Ivs+PelR2rUS0wSd0l/VzSbEmzJL0re/4wSU9kLc1nJY2Q1FvSPVmNz0n6UGt//8zM\nrPHa+pzZIcAPImJsRLwGfDUiJgGHA++RNLbEe/oAf4qIw4G/AhfWsW9FxFHAl4BCMH4BWB4RY4Fv\nAxOaUOs/AVsj4jDgw8DNWTfpZ4FrImI8cCSwFDgdWBwRh0fE24H7SxYofTIL1JkrV65sQilmZtYU\nbR1mL0XEzKLH50maBcwCxgClwmxzRNyTrT8JVNWx71+V2OZ44HaAiHiG1CJsrOOBW7L3Pk8KrVHA\no8DXJX0ZGBYRW4BngSlZ6/C4iFhXaocRcUNETIqISQMHDmxCKWZm1hRtHWabCiuSRgP/DJwYEeOA\ne4G9S7xnW9H6Tuo+r7e1Edu0WETcDLw/O969kt4VEXOASaSwvErSpW11fDMza1h7Ds3fB9gArJe0\nP3BqGxzjL8DZkM51UbrlV5dHgPOz944B9gcWSBoREQsi4ofAb4FxkoaQBrrcDHwPOKIVP4OZmTVR\nm7VoSpgFvAC8CLxMCp7W9mPg/yS9kB3rBaBkFyDwB0nbs/VHSOfmrpc0G9gO/GNEbJM0VdJ52XNL\ngcuBd5BaZNWkluSn2+CzmJlZIykiyl1Dq5HUBegSEVuybs37gNERsaPMpTFp0qSYOXNmwxuamdlb\nJD2ZDRysV3u2zNpDL+CBLNQEfKoSgszMzNpWhwqziFgLTCx3HWZm1r58b0YzM8s9h5mZmeVehxoA\nUskkrSSN4myOAcAbrVhOW8pTrZCvevNUK+Sr3jzVCvmqt6W1HhQRDd51wmGWA5JmNmY0TyXIU62Q\nr3rzVCvkq9481Qr5qre9anU3o5mZ5Z7DzMzMcs9hlg83lLuAJshTrZCvevNUK+Sr3jzVCvmqt11q\n9TkzMzPLPbfMzMws9xxmZmaWew6zCiZpiqS5khZI+mq566mPpGGSHpL0gqTnJf1zuWtqiKTOkp6S\n9Nty19IQSX0l3SXpRUlzJB1b7prqIulfsn8Dz0m6TVKpeQvLRtL/SFoh6bmi5/pJul/S/OzrvuWs\nsVgd9V6d/Vt4VtLdkvqWs8aCUrUWvXaJpJA0oC2O7TCrUJI6A9cCp5HmZTtPUlPmZ2tvO4BLImIs\ncAzwuQqvF9JksXPKXUQj/RC4NyIOAQ6nQuvO5vr7J2BSRLwd6AycW96qdnMTMKXWc18FHoiI0cAD\n2eNKcRO713s/8PZsouN5wNfdVj/EAAAC0UlEQVTau6g63MTutSJpGHAK8EpbHdhhVrmOAhZExMKI\n2AbcDryvzDXVKSKWRcSsbH0D6ZftkPJWVTdJQ4H3AjeWu5aGSOoDvAv4GUBEbMtuql2pugDds9kr\nepDmAawYEfEwsLrW0+8Dfp6t/xz4u3Ytqh6l6o2I+4pmBPkbMLTdCyuhju8twA+ALwNtNuLQYVa5\nhgCvFj1eQgWHQzFJVcAE4LHyVlKv/yT956oudyGNMBxYCfxv1i16o6Se5S6qlIh4DbiG9Bf4MmBd\nRNxX3qoaZXBELMvWlwODy1lME10I3FPuIuoi6X3AaxHxTFsex2FmrUpSL+CXwEURsb7c9ZQi6Qxg\nRUQ8We5aGqkLcARwXURMADZRWd1gb8nONb2PFMAHAD0l/UN5q2qaSNcr5eKaJUmXkbr4by13LaVI\n6gFcCnyjrY/lMKtcrwHDih4PzZ6rWJK6koLs1oj4VbnrqcdxwFmSFpO6b0+UdEt5S6rXEmBJRBRa\nuneRwq0SnQwsioiVEbEd+BXwjjLX1BivS9ofIPu6osz1NEjSR4AzgPOjci8YHkn6w+aZ7P/bUGCW\npP1a+0AOs8r1BDBa0nBJe5FOov+6zDXVSZJI53TmRMT3y11PfSLiaxExNCKqSN/XByOiYlsPEbEc\neFXSwdlTJwEvlLGk+rwCHCOpR/Zv4iQqdLBKLb8GLsjWLwCml7GWBkmaQuomPysi3ix3PXWJiNkR\nMSgiqrL/b0uAI7J/063KYVahspO7nwf+QPplcGdEPF/equp1HPBhUivn6Ww5vdxFdSBfAG6V9Cww\nHvhOmespKWs93gXMAmaTfsdU1K2XJN0G/BU4WNISSR8DrgLeI2k+qXV5VTlrLFZHvT8BegP3Z//X\n/rusRWbqqLV9jl25rVMzM7PGccvMzMxyz2FmZma55zAzM7Pcc5iZmVnuOczMzCz3HGZmZpZ7DjMz\nM8u9/w+/inuxUZRBtgAAAABJRU5ErkJggg==\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "LqL6FYUrtXpf",
        "colab_type": "code",
        "colab": {
          "resources": {
            "http://localhost:8080/nbextensions/google.colab/files.js": {
              "data": "Ly8gQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQwovLwovLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgovLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLy8KLy8gICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLy8KLy8gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQovLyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAovLyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLy8gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAovLyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCi8qKgogKiBAZmlsZW92ZXJ2aWV3IEhlbHBlcnMgZm9yIGdvb2dsZS5jb2xhYiBQeXRob24gbW9kdWxlLgogKi8KKGZ1bmN0aW9uKHNjb3BlKSB7CmZ1bmN0aW9uIHNwYW4odGV4dCwgc3R5bGVBdHRyaWJ1dGVzID0ge30pIHsKICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpOwogIGVsZW1lbnQudGV4dENvbnRlbnQgPSB0ZXh0OwogIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHN0eWxlQXR0cmlidXRlcykpIHsKICAgIGVsZW1lbnQuc3R5bGVba2V5XSA9IHN0eWxlQXR0cmlidXRlc1trZXldOwogIH0KICByZXR1cm4gZWxlbWVudDsKfQoKLy8gTWF4IG51bWJlciBvZiBieXRlcyB3aGljaCB3aWxsIGJlIHVwbG9hZGVkIGF0IGEgdGltZS4KY29uc3QgTUFYX1BBWUxPQURfU0laRSA9IDEwMCAqIDEwMjQ7Ci8vIE1heCBhbW91bnQgb2YgdGltZSB0byBibG9jayB3YWl0aW5nIGZvciB0aGUgdXNlci4KY29uc3QgRklMRV9DSEFOR0VfVElNRU9VVF9NUyA9IDMwICogMTAwMDsKCmZ1bmN0aW9uIF91cGxvYWRGaWxlcyhpbnB1dElkLCBvdXRwdXRJZCkgewogIGNvbnN0IHN0ZXBzID0gdXBsb2FkRmlsZXNTdGVwKGlucHV0SWQsIG91dHB1dElkKTsKICBjb25zdCBvdXRwdXRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQob3V0cHV0SWQpOwogIC8vIENhY2hlIHN0ZXBzIG9uIHRoZSBvdXRwdXRFbGVtZW50IHRvIG1ha2UgaXQgYXZhaWxhYmxlIGZvciB0aGUgbmV4dCBjYWxsCiAgLy8gdG8gdXBsb2FkRmlsZXNDb250aW51ZSBmcm9tIFB5dGhvbi4KICBvdXRwdXRFbGVtZW50LnN0ZXBzID0gc3RlcHM7CgogIHJldHVybiBfdXBsb2FkRmlsZXNDb250aW51ZShvdXRwdXRJZCk7Cn0KCi8vIFRoaXMgaXMgcm91Z2hseSBhbiBhc3luYyBnZW5lcmF0b3IgKG5vdCBzdXBwb3J0ZWQgaW4gdGhlIGJyb3dzZXIgeWV0KSwKLy8gd2hlcmUgdGhlcmUgYXJlIG11bHRpcGxlIGFzeW5jaHJvbm91cyBzdGVwcyBhbmQgdGhlIFB5dGhvbiBzaWRlIGlzIGdvaW5nCi8vIHRvIHBvbGwgZm9yIGNvbXBsZXRpb24gb2YgZWFjaCBzdGVwLgovLyBUaGlzIHVzZXMgYSBQcm9taXNlIHRvIGJsb2NrIHRoZSBweXRob24gc2lkZSBvbiBjb21wbGV0aW9uIG9mIGVhY2ggc3RlcCwKLy8gdGhlbiBwYXNzZXMgdGhlIHJlc3VsdCBvZiB0aGUgcHJldmlvdXMgc3RlcCBhcyB0aGUgaW5wdXQgdG8gdGhlIG5leHQgc3RlcC4KZnVuY3Rpb24gX3VwbG9hZEZpbGVzQ29udGludWUob3V0cHV0SWQpIHsKICBjb25zdCBvdXRwdXRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQob3V0cHV0SWQpOwogIGNvbnN0IHN0ZXBzID0gb3V0cHV0RWxlbWVudC5zdGVwczsKCiAgY29uc3QgbmV4dCA9IHN0ZXBzLm5leHQob3V0cHV0RWxlbWVudC5sYXN0UHJvbWlzZVZhbHVlKTsKICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5leHQudmFsdWUucHJvbWlzZSkudGhlbigodmFsdWUpID0+IHsKICAgIC8vIENhY2hlIHRoZSBsYXN0IHByb21pc2UgdmFsdWUgdG8gbWFrZSBpdCBhdmFpbGFibGUgdG8gdGhlIG5leHQKICAgIC8vIHN0ZXAgb2YgdGhlIGdlbmVyYXRvci4KICAgIG91dHB1dEVsZW1lbnQubGFzdFByb21pc2VWYWx1ZSA9IHZhbHVlOwogICAgcmV0dXJuIG5leHQudmFsdWUucmVzcG9uc2U7CiAgfSk7Cn0KCi8qKgogKiBHZW5lcmF0b3IgZnVuY3Rpb24gd2hpY2ggaXMgY2FsbGVkIGJldHdlZW4gZWFjaCBhc3luYyBzdGVwIG9mIHRoZSB1cGxvYWQKICogcHJvY2Vzcy4KICogQHBhcmFtIHtzdHJpbmd9IGlucHV0SWQgRWxlbWVudCBJRCBvZiB0aGUgaW5wdXQgZmlsZSBwaWNrZXIgZWxlbWVudC4KICogQHBhcmFtIHtzdHJpbmd9IG91dHB1dElkIEVsZW1lbnQgSUQgb2YgdGhlIG91dHB1dCBkaXNwbGF5LgogKiBAcmV0dXJuIHshSXRlcmFibGU8IU9iamVjdD59IEl0ZXJhYmxlIG9mIG5leHQgc3RlcHMuCiAqLwpmdW5jdGlvbiogdXBsb2FkRmlsZXNTdGVwKGlucHV0SWQsIG91dHB1dElkKSB7CiAgY29uc3QgaW5wdXRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaW5wdXRJZCk7CiAgaW5wdXRFbGVtZW50LmRpc2FibGVkID0gZmFsc2U7CgogIGNvbnN0IG91dHB1dEVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChvdXRwdXRJZCk7CiAgb3V0cHV0RWxlbWVudC5pbm5lckhUTUwgPSAnJzsKCiAgY29uc3QgcGlja2VkUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7CiAgICBpbnB1dEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKGUpID0+IHsKICAgICAgcmVzb2x2ZShlLnRhcmdldC5maWxlcyk7CiAgICB9KTsKICB9KTsKCiAgY29uc3QgY2FuY2VsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7CiAgaW5wdXRFbGVtZW50LnBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoY2FuY2VsKTsKICBjYW5jZWwudGV4dENvbnRlbnQgPSAnQ2FuY2VsIHVwbG9hZCc7CiAgY29uc3QgY2FuY2VsUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7CiAgICBjYW5jZWwub25jbGljayA9ICgpID0+IHsKICAgICAgcmVzb2x2ZShudWxsKTsKICAgIH07CiAgfSk7CgogIC8vIENhbmNlbCB1cGxvYWQgaWYgdXNlciBoYXNuJ3QgcGlja2VkIGFueXRoaW5nIGluIHRpbWVvdXQuCiAgY29uc3QgdGltZW91dFByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gewogICAgc2V0VGltZW91dCgoKSA9PiB7CiAgICAgIHJlc29sdmUobnVsbCk7CiAgICB9LCBGSUxFX0NIQU5HRV9USU1FT1VUX01TKTsKICB9KTsKCiAgLy8gV2FpdCBmb3IgdGhlIHVzZXIgdG8gcGljayB0aGUgZmlsZXMuCiAgY29uc3QgZmlsZXMgPSB5aWVsZCB7CiAgICBwcm9taXNlOiBQcm9taXNlLnJhY2UoW3BpY2tlZFByb21pc2UsIHRpbWVvdXRQcm9taXNlLCBjYW5jZWxQcm9taXNlXSksCiAgICByZXNwb25zZTogewogICAgICBhY3Rpb246ICdzdGFydGluZycsCiAgICB9CiAgfTsKCiAgaWYgKCFmaWxlcykgewogICAgcmV0dXJuIHsKICAgICAgcmVzcG9uc2U6IHsKICAgICAgICBhY3Rpb246ICdjb21wbGV0ZScsCiAgICAgIH0KICAgIH07CiAgfQoKICBjYW5jZWwucmVtb3ZlKCk7CgogIC8vIERpc2FibGUgdGhlIGlucHV0IGVsZW1lbnQgc2luY2UgZnVydGhlciBwaWNrcyBhcmUgbm90IGFsbG93ZWQuCiAgaW5wdXRFbGVtZW50LmRpc2FibGVkID0gdHJ1ZTsKCiAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7CiAgICBjb25zdCBsaSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpJyk7CiAgICBsaS5hcHBlbmQoc3BhbihmaWxlLm5hbWUsIHtmb250V2VpZ2h0OiAnYm9sZCd9KSk7CiAgICBsaS5hcHBlbmQoc3BhbigKICAgICAgICBgKCR7ZmlsZS50eXBlIHx8ICduL2EnfSkgLSAke2ZpbGUuc2l6ZX0gYnl0ZXMsIGAgKwogICAgICAgIGBsYXN0IG1vZGlmaWVkOiAkewogICAgICAgICAgICBmaWxlLmxhc3RNb2RpZmllZERhdGUgPyBmaWxlLmxhc3RNb2RpZmllZERhdGUudG9Mb2NhbGVEYXRlU3RyaW5nKCkgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbi9hJ30gLSBgKSk7CiAgICBjb25zdCBwZXJjZW50ID0gc3BhbignMCUgZG9uZScpOwogICAgbGkuYXBwZW5kQ2hpbGQocGVyY2VudCk7CgogICAgb3V0cHV0RWxlbWVudC5hcHBlbmRDaGlsZChsaSk7CgogICAgY29uc3QgZmlsZURhdGFQcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHsKICAgICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsKICAgICAgcmVhZGVyLm9ubG9hZCA9IChlKSA9PiB7CiAgICAgICAgcmVzb2x2ZShlLnRhcmdldC5yZXN1bHQpOwogICAgICB9OwogICAgICByZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoZmlsZSk7CiAgICB9KTsKICAgIC8vIFdhaXQgZm9yIHRoZSBkYXRhIHRvIGJlIHJlYWR5LgogICAgbGV0IGZpbGVEYXRhID0geWllbGQgewogICAgICBwcm9taXNlOiBmaWxlRGF0YVByb21pc2UsCiAgICAgIHJlc3BvbnNlOiB7CiAgICAgICAgYWN0aW9uOiAnY29udGludWUnLAogICAgICB9CiAgICB9OwoKICAgIC8vIFVzZSBhIGNodW5rZWQgc2VuZGluZyB0byBhdm9pZCBtZXNzYWdlIHNpemUgbGltaXRzLiBTZWUgYi82MjExNTY2MC4KICAgIGxldCBwb3NpdGlvbiA9IDA7CiAgICB3aGlsZSAocG9zaXRpb24gPCBmaWxlRGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgIGNvbnN0IGxlbmd0aCA9IE1hdGgubWluKGZpbGVEYXRhLmJ5dGVMZW5ndGggLSBwb3NpdGlvbiwgTUFYX1BBWUxPQURfU0laRSk7CiAgICAgIGNvbnN0IGNodW5rID0gbmV3IFVpbnQ4QXJyYXkoZmlsZURhdGEsIHBvc2l0aW9uLCBsZW5ndGgpOwogICAgICBwb3NpdGlvbiArPSBsZW5ndGg7CgogICAgICBjb25zdCBiYXNlNjQgPSBidG9hKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgY2h1bmspKTsKICAgICAgeWllbGQgewogICAgICAgIHJlc3BvbnNlOiB7CiAgICAgICAgICBhY3Rpb246ICdhcHBlbmQnLAogICAgICAgICAgZmlsZTogZmlsZS5uYW1lLAogICAgICAgICAgZGF0YTogYmFzZTY0LAogICAgICAgIH0sCiAgICAgIH07CiAgICAgIHBlcmNlbnQudGV4dENvbnRlbnQgPQogICAgICAgICAgYCR7TWF0aC5yb3VuZCgocG9zaXRpb24gLyBmaWxlRGF0YS5ieXRlTGVuZ3RoKSAqIDEwMCl9JSBkb25lYDsKICAgIH0KICB9CgogIC8vIEFsbCBkb25lLgogIHlpZWxkIHsKICAgIHJlc3BvbnNlOiB7CiAgICAgIGFjdGlvbjogJ2NvbXBsZXRlJywKICAgIH0KICB9Owp9CgpzY29wZS5nb29nbGUgPSBzY29wZS5nb29nbGUgfHwge307CnNjb3BlLmdvb2dsZS5jb2xhYiA9IHNjb3BlLmdvb2dsZS5jb2xhYiB8fCB7fTsKc2NvcGUuZ29vZ2xlLmNvbGFiLl9maWxlcyA9IHsKICBfdXBsb2FkRmlsZXMsCiAgX3VwbG9hZEZpbGVzQ29udGludWUsCn07Cn0pKHNlbGYpOwo=",
              "ok": true,
              "headers": [
                [
                  "content-type",
                  "application/javascript"
                ]
              ],
              "status": 200,
              "status_text": ""
            }
          },
          "base_uri": "https://localhost:8080/",
          "height": 57
        },
        "outputId": "8ae59aea-e0a8-467f-a53b-e16c61551380"
      },
      "source": [
        "# Here's a codeblock just for fun. You should be able to upload an image here \n",
        "# and have it classified without crashing\n",
        "\n",
        "import numpy as np\n",
        "from google.colab import files\n",
        "from keras.preprocessing import image\n",
        "\n",
        "uploaded = files.upload()\n",
        "\n",
        "for fn in uploaded.keys():\n",
        " \n",
        "  # predicting images\n",
        "  path = '/content/' + fn\n",
        "  img = image.load_img(path, target_size=(150, 150))\n",
        "  x = image.img_to_array(img)\n",
        "  x = np.expand_dims(x, axis=0)\n",
        "\n",
        "  images = np.vstack([x])\n",
        "  classes = model.predict(images, batch_size=10)\n",
        "  print(classes[0])\n",
        "  if classes[0]>0.5:\n",
        "    print(fn + \" is a dog\")\n",
        "  else:\n",
        "    print(fn + \" is a cat\")"
      ],
      "execution_count": 12,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Using TensorFlow backend.\n"
          ],
          "name": "stderr"
        },
        {
          "output_type": "display_data",
          "data": {
            "text/html": [
              "\n",
              "     <input type=\"file\" id=\"files-52fd0bfd-4ae9-456d-ac75-c1873fd63037\" name=\"files[]\" multiple disabled />\n",
              "     <output id=\"result-52fd0bfd-4ae9-456d-ac75-c1873fd63037\">\n",
              "      Upload widget is only available when the cell has been executed in the\n",
              "      current browser session. Please rerun this cell to enable.\n",
              "      </output>\n",
              "      <script src=\"/nbextensions/google.colab/files.js\"></script> "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "LDxTPbgaQLky",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}